﻿
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.AddressableAssets.ResourceLocators;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.ResourceManagement.ResourceLocations;
using UnityEngine.ResourceManagement.ResourceProviders;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using zframe;

/// <summary>
/// Addressable相关
/// </summary>
public class AdressableLoadDemo : MonoBehaviour
{
    public Image testImg;
    public Button btn;

    void Start()
    {
        btn.onClick.AddListener(CheckUpdate); //加载场景
         
        
    }

    private void CheckUpdate()
    {
        Addressables.InitializeAsync().Completed += OnAddressInit;
    }

    private void OnAddressInit(AsyncOperationHandle<IResourceLocator> res)
    {
        Addressables.CheckForCatalogUpdates(false).Completed += (AsyncOperationHandle<List<string>> opt) => {

            if (opt.Result.Count > 0)
            {
                string keys = string.Join("_", opt.Result);
                ZLogger.Log("Addressables.CheckForCatalogUpdates 有改变 keys=" + keys);
                Addressables.UpdateCatalogs(opt.Result).Completed += (AsyncOperationHandle<List<IResourceLocator>> resOpt) => {
                    if (resOpt.Status != AsyncOperationStatus.Succeeded)
                    {
                        ZLogger.Log("Addressables.UpdateCatalogs 失败 resOpt.Status="+ resOpt.Status);
                        return;
                    }
                    if (resOpt.Result.Count > 0)
                    {
                        ZLogger.Log("Addressables.UpdateCatalogs 有资源更新 ");
                        List<object> updateKeys = new List<object>(); 
                        foreach (var item in resOpt.Result)
                        {
                           updateKeys.AddRange(item.Keys.ToList()); 
                        }
                        
                        Addressables.GetDownloadSizeAsync(updateKeys).Completed += (AsyncOperationHandle<long> obj) => {
                            if (obj.Status== AsyncOperationStatus.Succeeded)
                            {
                                ZLogger.Log("Addressables.GetDownloadSizeAsync 需要下载的大小=" + obj.Result);
                                TestDownload(updateKeys);
                            }
                        };
                        
                    }
                    else
                    {
                        ZLogger.Log("Addressables.UpdateCatalogs 没有资源更新 ");
                        
                    }
                    StartLoad();

                };
            }
            else
            {
                ZLogger.Log("Addressables.CheckForCatalogUpdates 没有改变++++");
                StartLoad();
            }

        };
    }

    private void TestDownload(List<object>  updateKeys)
    {
        AsyncOperationHandle<IList<IResourceLocation>> locHandler = Addressables.LoadResourceLocationsAsync(updateKeys);
        locHandler.Completed += Handler_Completed;
        Addressables.DownloadDependenciesAsync(updateKeys, Addressables.MergeMode.Union, false).Completed += (AsyncOperationHandle handler) =>
        {
            if (handler.Status != AsyncOperationStatus.Succeeded)
            {
                ZLogger.Log("Addressables.DownloadDependenciesAsync handler.Status=" + handler.Status);
                return;
            }
            ZLogger.Log("Addressables.DownloadDependenciesAsync handler.Result.GetType()=" + handler.Result.GetType());
            foreach (var item in handler.Result as List<UnityEngine.ResourceManagement.ResourceProviders.IAssetBundleResource>)
            {
                var ab = item.GetAssetBundle();
                ZLogger.Log("Addressables.DownloadDependenciesAsync ab name=" + ab.name);
                foreach (var name in ab.GetAllAssetNames())
                {
                    ZLogger.Log("Addressables.DownloadDependenciesAsync asset name " + name);
                }
            }
        };

    }

    private void Handler_Completed(AsyncOperationHandle<IList<IResourceLocation>> obj)
    {
        ZLogger.Log(obj.Result.Count);
    }

    private void StartLoad()
    {
        ZLogger.Log("Addressables.InitializeAsync=");

        //加载单个资源
        //var opt = Addressables.LoadAssetAsync<Sprite>("Assets/addressableAtlas/04zi.png");
        //opt.Completed += Opt_Completed;
        //异步实例化
        Addressables.InstantiateAsync("Assets/AddressPrefabs/redContent.prefab", GameObject.Find("Canvas").transform);
        //addPrefabs

        //加载多个资源
        //通过标签itemBg加载资源，
        //无法通过文件夹路径加载多个
        //例如Assets/addressableAtlas  下有多个sprite 不能通过Assets/addressableAtlas加载多个sprite
        /*
        var opt2 = Addressables.LoadAssetsAsync<Sprite>("itemBg", (Sprite sp) => {
            ZLogger.Log("AdressableLoadDemo addPrefabs sp="+ sp.name); //逐个回调
        });
       

        opt2.Completed += (AsyncOperationHandle<IList<Sprite>> obj) => { //全部加载完成
            ZLogger.Log("AdressableLoadDemo blueBtn2.prefab loaded");
        };
         */
        //加载依赖
        //Addressables.DownloadDependenciesAsync("itemBg")

        //var catalog = "catalog_2023.12.12.04.09.43.json";
        //加载地址条目文件
        //Addressables.LoadContentCatalogAsync(catalog).Completed += AdressableLoadDemo_Completed;
    }

    private void AdressableLoadDemo_Completed(AsyncOperationHandle<UnityEngine.AddressableAssets.ResourceLocators.IResourceLocator> obj)
    {
        ZLogger.Log("AdressableLoadDemo_Completed");
    }

    private void Opt_Completed(AsyncOperationHandle<Sprite> obj)
    {
        Debug.Log("AdressableLoadDemo obj.Result=" + obj.Status);
        if (testImg != null && obj.Status == AsyncOperationStatus.Succeeded)
        {
            testImg.sprite = obj.Result;
        }
    }

    private void LoadScene()
    {
        
        var opt = Addressables.LoadSceneAsync("Assets/addressScenes/AddressMainUI.unity",LoadSceneMode.Additive);
        opt.Completed += (AsyncOperationHandle<SceneInstance> obj) =>{
            Debug.Log("Addressables LoadScene++++ 场景加载完成");
        }; 
    }

    private void OperationHandle_Completed(AsyncOperationHandle obj)
    {
        
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    [RuntimeInitializeOnLoadMethod]
    static void SetIntervalIdTransform()
    {
        Addressables.InternalIdTransformFunc = GetIntervalIdTransform;
    }

    static string GetIntervalIdTransform(IResourceLocation location) {

        ZLogger.Log("GetIntervalIdTransform location.InternalId=" + location.InternalId);
        if (location.ResourceType == typeof(IAssetBundleResource) && location.InternalId.StartsWith("http"))
        {
            
            return location.InternalId+"?version="+DateTimeOffset.Now.ToUnixTimeMilliseconds();
        }
        return location.InternalId;
    }

}
